
package vv.lines.view.swing;

import vv.lines.core.ActionId;
import vv.lines.core.Ball;
import vv.lines.core.IActionHandler;
import vv.lines.store.GameChampion;
import vv.lines.utils.TextResources;
import vv.lines.view.View;
import vv.lines.view.WindowView;
import vv.lines.view.swing.utils.ActionHolder;
import vv.lines.view.swing.utils.SwingResourceHolder;

import javax.swing.*;
import java.awt.*;
import java.util.List;

import static java.awt.Font.BOLD;
import static java.awt.Font.ITALIC;
import static javax.swing.BorderFactory.createEmptyBorder;
import static javax.swing.SwingConstants.RIGHT;
import static vv.lines.core.ActionId.EXIT;
import static vv.lines.core.ActionId.NEW_GAME;
import static vv.lines.utils.TextResources.*;

/**
 *
 * @author vpotapenko
 */
public class SwingWindowView extends JFrame implements WindowView {

    private ActionHolder actionHolder;
    private SwingResourceHolder resourceHolder;

    private JLabel scoreLabel;
    private Box nextBallsBox;
    private Box championsBox;

    public SwingWindowView(IActionHandler actionHandler, SwingResourceHolder resourceHolder) {
        this.resourceHolder = resourceHolder;
        actionHolder = new ActionHolder(actionHandler, resourceHolder);

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setIconImage(resourceHolder.getGameImage());

        getContentPane().setLayout(new BorderLayout());

        initControls();
    }

    private void initControls() {
        JToolBar toolBar = new JToolBar();

        JButton button = toolBar.add(actionHolder.getAction(NEW_GAME));
        button.setFocusable(false);

        toolBar.addSeparator();
        toolBar.add(createNextBallsPanel());
        toolBar.addSeparator();
        toolBar.add(createScorePanel());
        toolBar.addSeparator();

        toolBar.setFloatable(false);
        toolBar.setRollover(true);
        getContentPane().add(toolBar, BorderLayout.NORTH);

        getContentPane().add(createChampionsPanel(), BorderLayout.EAST);
        initMenu();
    }

    private void initMenu() {
        JMenuBar menuBar = new JMenuBar();

        JMenu menu = new JMenu(FILE);
        menu.add(actionHolder.getAction(NEW_GAME));
        menu.addSeparator();
        menu.add(actionHolder.getAction(EXIT));
        menuBar.add(menu);

        menu = new JMenu(HELP);
        menu.add(actionHolder.getAction(ActionId.RULES));
        menu.add(actionHolder.getAction(ActionId.ABOUT));
        menuBar.add(menu);

        setJMenuBar(menuBar);
    }

    private Component createChampionsPanel() {
        Box box = Box.createVerticalBox();
        box.add(createChampionsLabel());
        championsBox = Box.createVerticalBox();
        box.add(championsBox);

        box.setBorder(BorderFactory.createEtchedBorder());
        return box;
    }

    private JLabel createChampionsLabel() {
        final JLabel label = new JLabel(CHAMPIONS_LABEL);
        label.setAlignmentX(LEFT_ALIGNMENT);

        Font font = label.getFont();
        label.setFont(font.deriveFont(Font.BOLD));

        return label;
    }

    private Component createNextBallsPanel() {
        Box box = Box.createHorizontalBox();
        box.add(new JLabel(NEXT_BALLS_LABEL));

        nextBallsBox = Box.createHorizontalBox();
        box.add(nextBallsBox);

        return box;
    }

    private JComponent createScorePanel() {
        Box box = Box.createHorizontalBox();

        box.add(new JLabel(TextResources.SCORE_LABEL));

        scoreLabel = new JLabel();
        Font font = scoreLabel.getFont();
        scoreLabel.setFont(font.deriveFont(BOLD | ITALIC, font.getSize() + 1));
        scoreLabel.setHorizontalAlignment(RIGHT);
        scoreLabel.setBorder(createEmptyBorder(2, 5, 2, 5));
        box.add(scoreLabel);

        return box;
    }

    public void setFieldView(View fieldView) {
        getContentPane().add((JComponent) fieldView, BorderLayout.CENTER);
    }

    @Override
    public void setVisible(boolean b) {
        if (b == isVisible()) return;

        // todo
        if (b) {
            pack();
            setLocationRelativeTo(null);
        }

        super.setVisible(b);
    }

    public void updateScore(int score) {
        scoreLabel.setText(String.valueOf(score));
    }

    public void updateNextBalls(List<Ball> nextBalls) {
        for (int i = 0; i < nextBalls.size(); i++) {
            JLabel label = getNextBallLabel(i);
            label.setIcon(resourceHolder.getPreviewIcon(nextBalls.get(i).getValue()));
        }
    }

    public void updateChampions(List<GameChampion> champions) {
        championsBox.removeAll();
        for (int i = 0; i < champions.size(); i++) {
            championsBox.add(createChampionItem(champions.get(i), i));
        }
        championsBox.revalidate();
    }

    private JComponent createChampionItem(GameChampion champion, int index) {
        Box box = Box.createHorizontalBox();
        box.setAlignmentX(Component.LEFT_ALIGNMENT);

        box.add(new JLabel(resourceHolder.getChampionIcon((index + 1) % 8)));

        JLabel label = new JLabel(champion.getName());
        label.setBorder(createEmptyBorder(0, 0, 0, 15));
        label.setFont(label.getFont().deriveFont(Font.ITALIC));
        box.add(label);

        label = new JLabel(String.valueOf(champion.getScore()));
        label.setBorder(createEmptyBorder(0, 0, 0, 5));
        box.add(label);

        return box;
    }

    private JLabel getNextBallLabel(int i) {
        if (i < nextBallsBox.getComponentCount()) return (JLabel) nextBallsBox.getComponent(i);

        JLabel label = new JLabel();
        nextBallsBox.add(label);

        return label;
    }
}
